package com.lry.basic.handler;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * //不加锁，供不应求 ，供大于求
 * Created by Administrator on 2017/5/29.
 */

public class MessageQueue {

    Message[]items;//消息数组
    int putIndex;//入队索引
    int takeIndex;//出队索引
    int count=0;//消息个数
    Lock lock;//添加锁 阻塞队列 java高并发编程
    Condition notEmpty;//消费者
    Condition notFull;//生产者
    public MessageQueue(){
        this.items=new Message[50];
        this.lock=new ReentrantLock();
        this.notEmpty=lock.newCondition();
        this.notFull=lock.newCondition();
    }
    /**
     * 消息入队（生产者） sendMessage()里面调用是子线程
     * @param msg
     */
    public void enqueueMessage(Message msg){
        try {
            lock.lock();//加锁
            if (count == items.length) {
                //阻塞 已经满了，不能在生产了
                notFull.await();
            }
            items[putIndex] = msg;
            putIndex = (++putIndex == items.length) ? 0 : putIndex;
           //队列不为空，通知消费者线程可以消费
            notEmpty.signalAll();//防止多个子线程 没有唤醒
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        count++;
    }

    /**
     * 消息出队（消费者）  looper调用 ，是主线程
     * @r  */
    public Message next(){
        Message msg=null;
        try {
            lock.lock();
            //没有产品了，不能消费
            while(count==0){
                notEmpty.await();
            }
            msg = items[takeIndex];
            items[takeIndex] = null;//出队后置空
            takeIndex = (++takeIndex == items.length) ? 0 : takeIndex;
            count--;
            notFull.signalAll();//防止多个子线程 没有唤醒
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return msg;
    }
}
